package com.mock.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.mock.dao.ContactDao;
import com.mock.model.Contact;
import com.mock.model.DataTable;
import com.mock.utils.HibernateUtil;

public class ContactDaoImpl extends GenericDaoImpl<Contact, Long> implements ContactDao {

	@Override
	public List<Contact> getAllContact() {
		return super.getAll(Contact.class);
	}

	@Override
	public Contact getContactById(long id) {
		return super.getById(Contact.class, id);
	}

	@Override
	public Contact getById(Long id) {
		return super.getById(Contact.class, id);
	}

	@Override
	public Contact getByName(String name) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		String[] str = name.split(" ");
		String firstname = str[0].toString();
		String surname = str[1].toString();

		Query query = (Query) session
				.createQuery("from Contact c where c.firstname=:firstname and c.surname=:surname");
		query.setParameter("firstname", firstname);
		query.setParameter("surname", surname);
		Contact contact = (Contact) query.uniqueResult();
		if (null != contact)
			return contact;
		return null;
	}

	@Override
	public List<Contact> getContactByQuery(DataTable datatable) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		Criteria criteria = session.createCriteria(Contact.class, "contact");
		criteria.createAlias("contact.contactType", "contactType");
		criteria.setFetchMode("contact.contactType", FetchMode.JOIN);

		// Get Sort Column Name
		String columnName = "id";
		switch (datatable.iSortCol_0) {
		case 0:
			columnName = "id";
			break;
		case 1:
			if ("asc".equalsIgnoreCase(datatable.sSortDir_0)) {
				criteria.addOrder(Order.asc("firstname"));
				criteria.addOrder(Order.asc("surname"));
			} else {
				criteria.addOrder(Order.desc("firstname"));
				criteria.addOrder(Order.desc("surname"));
			}
			break;
		case 2:
			columnName = "mobilePhone";
			break;
		case 3:
			columnName = "email";
			break;
		case 4:
			columnName = "contactType.type";
			break;
		case 5:
			columnName = "active";
			break;
		default:
			break;
		}

		// Search
		if (datatable.sSearch_6 == null && datatable.sSearch_7 == null) {

		} else {
			criteria.add(Restrictions.ilike("firstname", datatable.sSearch_6 + "%"));
			criteria.add(Restrictions.ilike("surname", datatable.sSearch_7 + "%"));			
		}

		// Get Sort Direction
		if ("asc".equalsIgnoreCase(datatable.sSortDir_0)
				&& datatable.iSortCol_0 != 1) {
			criteria.addOrder(Order.asc(columnName));
		} else {
			criteria.addOrder(Order.desc(columnName));
		}
		// Filter in-active
		if ("".equalsIgnoreCase(datatable.sSearch_5)) {

		} else if ("Yes".equalsIgnoreCase(datatable.sSearch_5)) {
			criteria.add(Restrictions.eq("active", true));
		}

		// Paging
		criteria.setFirstResult(datatable.iDisplayStart);
		criteria.setMaxResults(datatable.iDisplayLength);

		List<Contact> contacts = criteria.list();
		session.getTransaction().commit();
		return contacts;
	}

	@Override
	public int getRowCount() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		int count = ((Long) session.createQuery("select count(*) from Contact")
				.uniqueResult()).intValue();
		session.getTransaction().commit();
		return count;
	}
	
}
